package com.volunteer.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.volunteer.common.BusinessException;
import com.volunteer.common.Result;
import com.volunteer.common.ResultCode;
import com.volunteer.entity.User;
import com.volunteer.mapper.UserMapper;
import com.volunteer.model.PasswordUpdateDTO;
import com.volunteer.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;

/**
 * 用户服务实现类
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public Result login(String username, String password) {
        // 参数校验
        if (username == null || password == null) {
            return Result.error("用户名和密码不能为空");
        }

        // 查询用户
        User user = this.getOne(new LambdaQueryWrapper<User>()
                .eq(User::getName, username));

        // 验证用户存在且密码正确
        if (user == null || !BCrypt.checkpw(password, user.getPassword())) {
            return Result.error("用户名或密码错误");
        }

        // 检查用户状态
        if (user.getStatus() != 1) {
            return Result.error("账号已被禁用");
        }

        // 生成token
        StpUtil.login(user.getId());

        // 清除敏感信息
        user.setPassword(null);

        // 构建返回数据
        Map<String, Object> data = new HashMap<>();
        data.put("user", user);
        data.put("token", StpUtil.getTokenValue());

        return Result.success(data);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result register(User user) {
        // 参数校验
        if (user.getName() == null || user.getPassword() == null) {
            return Result.error("用户名和密码不能为空");
        }

        // 检查用户名是否已存在
        long count = this.count(new LambdaQueryWrapper<User>()
                .eq(User::getName, user.getName()));
        if (count > 0) {
            return Result.error("用户名已存在");
        }

        // 加密密码
        user.setPassword(BCrypt.hashpw(user.getPassword()));

        // 设置默认值
        user.setRole(3); // 普通志愿者
        user.setStatus(1); // 正常状态
        user.setGender(1);
        user.setIsInfoCompleted(0); // 未完善资料

        // 保存用户
        boolean success = this.save(user);
        if (!success) {
            return Result.error("注册失败");
        }

        return Result.success("注册成功");
    }

    public static void main(String[] args) {
        System.out.println(BCrypt.hashpw("123456"));
    }

    @Override
    public Result logout() {
        StpUtil.logout();
        return Result.success("退出成功");
    }

    @Override
    public Result getUserInfo() {
        // 获取当前登录用户ID
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询用户信息
        User user = this.getById(userId);
        if (user == null) {
            return Result.error("用户不存在");
        }

        // 清除敏感信息
        user.setPassword(null);

        return Result.success(user);
    }

    /**
     * 根据学号查询用户
     *
     * @param studentId 学号
     * @return 用户信息
     */
    @Override
    public User getByStudentId(String studentId) {
        if (studentId == null) {
            return null;
        }
        return getOne(new LambdaQueryWrapper<User>()
                .eq(User::getStudentId, studentId));
    }

    @Override
    public boolean updateUserInfo1(User user) {
        return false;
    }

    /**
     * 更新用户信息（返回Result）
     *
     * @param user 用户信息
     * @return 操作结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateUserInfo(User user) {
        try {
            if (user == null) {
                return Result.error("用户信息不能为空");
            }

            // 获取当前登录用户ID
            Long userId = StpUtil.getLoginIdAsLong();
            user.setId(userId); // 确保只能修改自己的信息

            // 检查用户是否存在
            User existUser = this.getById(userId);
            if (existUser == null) {
                return Result.error("用户不存在");
            }

            // 不允许修改敏感信息
            user.setPassword(null);
            user.setRole(existUser.getRole());
            user.setStatus(existUser.getStatus());

            // 判断是否完善资料
            if (user.getName() != null && user.getGender() != null
                    && user.getPhone() != null && user.getQq() != null) {
                user.setIsInfoCompleted(1);
            }

            boolean success = this.updateById(user);
            if (success) {
                // 清除敏感信息
                user.setPassword(null);
                return Result.success(user);
            } else {
                return Result.error("更新用户信息失败");
            }
        } catch (Exception e) {
            log.error("更新用户信息失败", e);
            return Result.error("更新用户信息失败: " + e.getMessage());
        }
    }

    /**
     * 修改密码（返回Result）
     *
     * @param passwordUpdateDTO 密码修改DTO
     * @return 操作结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updatePassword(PasswordUpdateDTO passwordUpdateDTO) {
        try {
            if (passwordUpdateDTO == null ||
                passwordUpdateDTO.getOldPassword() == null ||
                passwordUpdateDTO.getNewPassword() == null) {
                return Result.error("密码信息不完整");
            }

            // 获取当前登录用户ID
            Long userId = StpUtil.getLoginIdAsLong();

            // 检查用户是否存在
            User user = this.getById(userId);
            if (user == null) {
                return Result.error("用户不存在");
            }

            // 校验旧密码
            if (!BCrypt.checkpw(passwordUpdateDTO.getOldPassword(), user.getPassword())) {
                return Result.error("旧密码错误");
            }

            // 更新密码
            user.setPassword(BCrypt.hashpw(passwordUpdateDTO.getNewPassword()));
            boolean success = this.updateById(user);

            if (success) {
                return Result.success("密码修改成功");
            } else {
                return Result.error("密码修改失败");
            }
        } catch (Exception e) {
            log.error("修改密码失败", e);
            return Result.error("修改密码失败: " + e.getMessage());
        }
    }

    /**
     * 重置密码
     *
     * @param studentId   学号
     * @param newPassword 新密码
     * @return 是否成功
     */
    @Override
    public boolean resetPassword(String studentId, String newPassword) {
        if (studentId == null || newPassword == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR);
        }

        // 检查用户是否存在
        User user = this.getByStudentId(studentId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_ACCOUNT_NOT_EXIST);
        }

        // 更新密码
        user.setPassword(BCrypt.hashpw(newPassword));
        return this.updateById(user);
    }

    /**
     * 分页查询用户列表
     *
     * @param page 分页参数
     * @param user 查询条件
     * @return 用户列表
     */
    @Override
    public Page<User> pageUsers(Page<User> page, User user) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();

        if (user != null) {
            // 按学号查询
            if (user.getStudentId() != null) {
                queryWrapper.like(User::getStudentId, user.getStudentId());
            }

            // 按姓名查询
            if (user.getName() != null) {
                queryWrapper.like(User::getName, user.getName());
            }

            // 按角色查询
            if (user.getRole() != null) {
                queryWrapper.eq(User::getRole, user.getRole());
            }

            // 按状态查询
            if (user.getStatus() != null) {
                queryWrapper.eq(User::getStatus, user.getStatus());
            }
        }

        return this.page(page, queryWrapper);
    }

    /**
     * 设置用户角色
     *
     * @param userId 用户ID
     * @param role   角色（0-普通志愿者 1-负责人 2-管理员）
     * @return 是否成功
     */
    @Override
    public boolean setUserRole(Long userId, Integer role) {
        if (userId == null || role == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR);
        }

        // 检查用户是否存在
        User user = this.getById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_ACCOUNT_NOT_EXIST);
        }

        // 更新角色
        user.setRole(role);
        return this.updateById(user);
    }

    /**
     * 启用/禁用用户
     *
     * @param userId 用户ID
     * @param status 状态（0-禁用 1-正常）
     * @return 是否成功
     */
    @Override
    public boolean setUserStatus(Long userId, Integer status) {
        if (userId == null || status == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR);
        }

        // 检查用户是否存在
        User user = this.getById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_ACCOUNT_NOT_EXIST);
        }

        // 更新状态
        user.setStatus(status);
        return this.updateById(user);
    }

    /**
     * 修改密码
     *
     * @param userId      用户ID
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return 是否成功
     */
    @Override
    public boolean updatePassword(Long userId, String oldPassword, String newPassword) {
        if (userId == null || oldPassword == null || newPassword == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR);
        }

        // 检查用户是否存在
        User user = this.getById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_ACCOUNT_NOT_EXIST);
        }

        // 校验旧密码
        if (!BCrypt.checkpw(oldPassword, user.getPassword())) {
            throw new BusinessException("旧密码错误");
        }

        // 更新密码
        user.setPassword(BCrypt.hashpw(newPassword));
        return this.updateById(user);
    }
}
